在 Day 15 我們讓 App 支援了多語言的語音辨識,但實際測試後發現一個問題,是Whisper 雖然聽得懂韓文、日文,但聽不懂飯圈專用的詞彙。
像是韓圈的「최애(最愛/本命)」、「컴백(回歸)」、「포카(小卡)」,這些詞在日常對話中很少出現,模型很容易把它們辨識成發音相近、但意思完全不同的字。例如把 최애 聽成 최외(最外圍)或 최선(盡力),整句話就變得怪,之後的翻譯也會跟著出錯。
其實 Whisper API 提供了一個 prompt 參數,只要事先告訴模型「接下來可能會出現這些詞」,它就會提高這些關鍵字的辨識權重。
所以今天我們要做的是:
在 **lib/features/live_translate/data/models/**下建立 fandom_dictionary.dart
/// 飯圈與專有名詞 Prompt 字典設定檔
class FandomDictionary {
// 韓圈常見術語與團體暱稱字典
static const String kpopPrompt = '''
K-POP, idol, BTS, SEVENTEEN, NCT, TWICE, NewJeans, IVE, aespa, Stray Kids,
방탄소년단, 세븐틴, 캐럿, 아미, 최애, 차애, 덕질, 입덕, 성덕, 컴백, 막콘, 첫콘,
포카, 양도, 스밍, 총공, 음중, 엠카, 인가, 생카, 굿즈
''';
// 日圈常見術語與應援字典
static const String jpopPrompt = '''
推し, 担当, アクスタ, アクキー, 缶バッジ, チェキ, ライブ, 遠征, 銀テープ,
推し活, 神席, ファンサ, 同担, 他担, 現場, 認知, 離脱, 生誕祭, 尊い, 沼
''';
/// 根據用戶選擇的類別,取得動態 Prompt 注入文字
static String getPromptForCategory(String category) {
switch (category) {
case 'kpop':
return kpopPrompt.replaceAll('\n', ' ').trim();
case 'jpop':
return jpopPrompt.replaceAll('\n', ' ').trim();
default:
return '';
}
}
}
whisper_service.dart 支援動態字典開啟你的 whisper_service.dart,在傳送給 Whisper API 時,將 語言 Prompt + 飯圈字典 Prompt 組合送出
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'dart:convert';
import '../models/fandom_dictionary.dart'; // 引用剛建立的字典
class MultiLangWhisperService {
final String _baseUrl = 'https://api.openai.com/v1/audio/transcriptions';
Future<String?> transcribe({
required File audioFile,
required String languageCode, // 'ko', 'ja', 'zh'
String category = 'kpop', // 預設載入 K-POP 字典
}) async {
final apiKey = dotenv.env['OPENAI_API_KEY'];
if (apiKey == null || apiKey.isEmpty) return null;
try {
var request = http.MultipartRequest('POST', Uri.parse(_baseUrl));
request.headers['Authorization'] = 'Bearer $apiKey';
request.fields['model'] = 'whisper-1';
request.fields['language'] = languageCode;
// 將「飯圈專有名詞字典」動態當作 prompt 傳給 Whisper
// Whisper 會提高這幾十個關鍵字的辨識權重!
final customPrompt = FandomDictionary.getPromptForCategory(category);
if (customPrompt.isNotEmpty) {
request.fields['prompt'] = customPrompt;
}
request.files.add(await http.MultipartFile.fromPath('file', audioFile.path));
var streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
if (response.statusCode == 200) {
var jsonResponse = jsonDecode(utf8.decode(response.bodyBytes));
return jsonResponse['text'];
} else {
print('辨識失敗: ${response.body}');
return null;
}
} catch (e) {
print('錯誤: $e');
return null;
}
}
}
選擇 K-POP 模式:在 App 畫面上把類別切換成 kpop。
對著手機講這句韓文(或用手機播放這段聲音)
「최애 컴백」(發音:Choi-ae come-back,意思是:最愛/推 回歸了)
看結果:
최애 變成「최외」(最外圍)、「최선」(盡力)、「최후」(最後)),就會覺得怪怪的최애 與 컴백 這兩個專有名詞!